//
// Created by Ukua on 2023/9/20.
//

#include "BSP_USB.h"

Bus_SubscriberTypeDef *g_bsp_usb_tx;
Bus_TopicHandleTypeDef *g_bsp_usb_rx;

fifo_t *g_usb_tx_fifo,
        *g_usb_rx_fifo;

osMessageQId g_usb_tx_queue,
        g_usb_rx_queue;

osThreadId BSP_USB_MainLoopTaskHandle;

//for cheryUSB
void usb_dc_low_level_init(void) {
    //初始化USB
    extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
    hpcd_USB_OTG_FS.Instance = USB_OTG_FS;
    HAL_PCD_MspInit(&hpcd_USB_OTG_FS);
}

//cheryUSB接收回调
void usbd_cdc_rx_callback(uint8_t *data, uint32_t len){
    INTF_UART_MessageTypeDef message;
    message.data = data;
    message.len = len;
    Bus_Publish(g_bsp_usb_rx,&message);
}


/**
 * @brief CAN标准发送话题回调函数
 * @param *message:消息
 * @param *topic:来源话题
 * @note 该函数会将消息储存在fifo中
 */
void BSP_USB_TX_CallBack(void *message, Bus_TopicHandleTypeDef *topic) {
    INTF_UART_MessageTypeDef *msg = (INTF_UART_MessageTypeDef *) message;
    //复制数据
    uint8_t *data = JUST_MALLOC(msg->len);
    memcpy(data, msg->data, msg->len);
    INTF_UART_MessageTypeDef new_msg;
    new_msg.len = msg->len;
    new_msg.data = data;
//    fifo_put(g_usb_tx_fifo, &new_msg);
//    JUST_FREE(msg->data);
    if (fifo_put(g_usb_tx_fifo, &new_msg) == -1) {
        JUST_FREE(new_msg.data);
    }
}

void BSP_USB_MainLoop() {
    while (1) {
        INTF_UART_MessageTypeDef msg;
        extern void cdc_acm_data_send(uint8_t busid, uint8_t *data, uint32_t len);
        //判断usb是否连接
            //发送消息
            while (!fifo_is_empty(g_usb_tx_fifo)) {
                fifo_get(g_usb_tx_fifo, &msg);
                cdc_acm_data_send(0, msg.data, msg.len);
                JUST_FREE(msg.data);
            }
//            if (!fifo_is_empty(g_can_rx_fifo)) {
//                fifo_get(g_can_rx_fifo, &msg);
//                Bus_Publish(g_can_rx, &msg);
//                JUST_FREE(msg.data);
//            }
        //虚拟串口接收
        osDelay(1);
    }
}

void BSP_USB_Init() {

    //注册话题
    g_bsp_usb_rx = Bus_TopicRegister(BSP_USB_RX_TOPIC_NAME);

    //订阅话题
    g_bsp_usb_tx = Bus_SubscribeFromName(BSP_USB_TX_TOPIC_NAME, BSP_USB_TX_CallBack);

    //FIFO初始化
    g_usb_tx_fifo = fifo_create(sizeof(INTF_UART_MessageTypeDef), BSP_USB_TX_FIFO_SIZE);

    //主循环任务
    osThreadDef(BSP_USB_MainLoop_Task, BSP_USB_MainLoop, osPriorityLow, 0, 256);
    BSP_USB_MainLoopTaskHandle = osThreadCreate(osThread(BSP_USB_MainLoop_Task), NULL);
}



